#!/usr/bin/python
# 使用说明示例：
# 服务端存放目录：.env文件中LOCKER_ROOT_DIR的值，缺省为~/locker目录
# - linux 客户端不以“/”开头
# python rsync-gen.py demo local/storage/demo
# - windows 客户端不包含盘符，不以“/”开头，第三个参数为盘符
# python rsync-gen.py demo local/storage/demo e

import sys
import os
import getpass
import subprocess
from dotenv import load_dotenv

dotenv_file = '.env'
exclude_file_name = 'rsync_exclude.txt'

def gen_linux(type, serv_dir, cli_dir):
    global exclude_file_name

    domain = os.getenv('DOMAIN', 'www.test.cn')
    rsync_user = os.getenv('RSYNC_USER', 'locker')
    rsync_module = os.getenv('RSYNC_MODULE', 'locker')

    content = get_tpl_content(type)
    cmd = content.replace('#%domain%#', domain)
    cmd = cmd.replace('#%rsync_user%#', rsync_user)
    cmd = cmd.replace('#%rsync_module%#', rsync_module)
    cmd = cmd.replace('#%server_dir%#', serv_dir)
    cmd = cmd.replace('#%client_path%#', cli_dir)
    cmd = cmd.replace('#%exclude_file_name%#', exclude_file_name)
    return cmd

def gen_linux_push(serv_dir, cli_dir):
    return gen_linux('push', serv_dir, cli_dir)

def gen_linux_pull(serv_dir, cli_dir):
    return gen_linux('pull', serv_dir, cli_dir)

def gen_win(type, serv_dir, drive, cli_dir):
    global exclude_file_name

    domain = os.getenv('DOMAIN', 'www.test.cn')
    rsync_user = os.getenv('RSYNC_USER', 'locker')
    rsync_module = os.getenv('RSYNC_MODULE', 'locker')

    content = get_tpl_content(type)
    cmd = content.replace('#%domain%#', domain)
    cmd = cmd.replace('#%rsync_user%#', rsync_user)
    cmd = cmd.replace('#%rsync_module%#', rsync_module)
    cmd = cmd.replace('#%server_dir%#', serv_dir)
    cmd = cmd.replace('#%client_path%#', cli_dir)
    cmd = cmd.replace('#%drive%#', drive)
    cmd = cmd.replace('#%exclude_file_name%#', exclude_file_name)
    cmd = cmd.replace("\r\n", "\n")
    cmd = cmd.replace("\n", "\r\n")
    return cmd

def gen_win_push(serv_dir, drive, cli_dir):
    return gen_win('push-cwrsync', serv_dir, drive, cli_dir)

def gen_win_pull(serv_dir, drive, cli_dir):
    return gen_win('pull-cwrsync', serv_dir, drive, cli_dir)

def change_owner(dir, user, group):
    cmd = "sudo chown -R {}:{} {}".format(user, group, dir)
    subprocess.run(cmd, shell=True)

def get_server_root_path():
    return os.getenv('LOCKER_ROOT_DIR', os.path.expanduser('~')+'/locker')

def get_server_path(serv_dir):
    return get_server_root_path()+'/'+serv_dir

def get_rsync_path(serv_dir):
    return get_server_path(serv_dir)+'/.rsync'

def get_exclude_file_path(dir):
    global exclude_file_name
    return dir+'/'+exclude_file_name
    
def get_current_path():
    return os.path.dirname(os.path.realpath(__file__))
    
def get_tpl_content(name):
    with open(get_current_path()+'/tpl/'+name+'.tpl', 'r') as file:
        content = file.read()
    return content

def show_file(type, map={}):
    with open(get_current_path()+'/txtfile/'+type+'.txt', 'r') as file:
        content = file.read()
    for key,value in map.items():
        content = content.replace(f'#%{key}%#', value)
    print(content)

def parse_dotenv():
    dotenv_path = get_current_path()+'/'+dotenv_file
    if os.path.exists(dotenv_path):
        load_dotenv(dotenv_path)
    
if __name__ == '__main__':
    arg_num = len(sys.argv)
    if arg_num == 1:
        show_file('help')
        os._exit(0)
    elif arg_num == 2:
        if sys.argv[1] == '--help' or sys.argv[1] == '-h':
            show_file('help')
            os._exit(0)
        if sys.argv[1] == '--usage' or sys.argv[1] == '-u':
            show_file('usage', {'server_root_dir':get_server_root_path()})
            os._exit(0)

        print('没有指定客户端目录')
        os._exit(0)

    parse_dotenv()

    # 服务端存放的目录，缺省以~/locker目录作为根目录
    server_dir = sys.argv[1]
    # 客户端存放的目录，linux为绝对路径，windows为不含盘符的绝对路径，根据>是否有输入第三个参数判断客户端是linux或是windows
    client_dir = sys.argv[2]
    # windows中的盘符
    win_drive = '' if arg_num < 4 else sys.argv[3]

    # 创建存放rsync执行命令的目录
    rsync_cmd_dir = get_rsync_path(server_dir)
    if not os.path.exists(rsync_cmd_dir):
        # os.system(f'sudo mkdir -p {rsync_cmd_dir}')
        os.system(f'mkdir -p {rsync_cmd_dir}')

    file_map = []
    if win_drive == '':
        file_map.append({'file':'push', 'content':gen_linux_push(server_dir, client_dir)})
        file_map.append({'file':'pull', 'content':gen_linux_pull(server_dir, client_dir)})

        win_drive = '盘符'
        client_dir = '内容目录'
        file_map.append({'file':'push-cwrsync.bat', 'content':gen_win_push(server_dir, win_drive, client_dir)})
        file_map.append({'file':'pull-cwrsync.bat', 'content':gen_win_pull(server_dir, win_drive, client_dir)})
    else:
        file_map.append({'file':'push-cwrsync.bat', 'content':gen_win_push(server_dir, win_drive, client_dir)})
        file_map.append({'file':'pull-cwrsync.bat', 'content':gen_win_pull(server_dir, win_drive, client_dir)})

        client_dir = '/内容目录'
        file_map.append({'file':'push', 'content':gen_linux_push(server_dir, client_dir)})
        file_map.append({'file':'pull', 'content':gen_linux_pull(server_dir, client_dir)})

    current_user = getpass.getuser()
    # change_owner(rsync_cmd_dir, current_user, current_user)

    with open(get_exclude_file_path(rsync_cmd_dir), 'w') as f:
        f.write('.rsync')

    for item in file_map:
        cmd_file = rsync_cmd_dir+'/'+item['file']
        
        with open(cmd_file, 'w') as f:
            f.write(item['content'])
            print("文件 "+item['file']+" 已生成")

    # change_owner(rsync_cmd_dir, 'root', 'root')
    # change_owner(get_server_path(server_dir), 'rsync', 'rsync')

    print("生成完成")
